package br.com.arg.aplica.util;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class ValidadorBean {
	private List<String> mensagens = new ArrayList<String>();;
	private String headerMensagem = "";
	private Properties prop = new Properties();
	private boolean haveProperties = false;

	// load a properties file
	public ValidadorBean() {
		try {
			InputStream in = getClass().getResourceAsStream(
					"/mensagens.properties");
			prop.load(in);
			in.close();
			haveProperties = true;
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public List<String> getMensagens() {
		return mensagens;
	}

	public void setMensagens(List<String> mensagens) {
		this.mensagens = mensagens;
	}

	public void validar(Object obj) throws Exception {
		if (!haveProperties) {
			System.out
					.println("++++++++++++++ Não consistido porque não possível abril a tabela de mensagens +++++++++++++++");
			mensagens
					.add("Não consistido porque não possível abril a tabela de mensagens");
			return;
		}

		Field[] fields = obj.getClass().getDeclaredFields();

		String[] nc = obj.getClass().getName().split("\\.");
		String nomeClasse = (nc.length > 0) ? nc[nc.length - 1] : "";
		for (Field field : fields) {
			headerMensagem = nomeClasse + ": campo " + field.getName() + " ";
			for (Annotation anotacao : field.getAnnotations()) {
				field.setAccessible(true);
				boolean isVazio = (field.get(obj) == null)
						|| (field.get(obj).toString().length() == 0);
				if (anotacao instanceof EhCPF) {
					if (isVazio)
						addMensagem("isVazio");
					else if (!CPF.valida(field.get(obj).toString()))
						addMensagem("nocpf");
				}

				if (anotacao instanceof EhCNPJ) {
					if (isVazio)
						addMensagem("isVazio");
					else if (!CNPJ.valida(field.get(obj).toString()))
						addMensagem("nocnpj");
				}

				if (anotacao instanceof EhNome) {
					if (isVazio)
						addMensagem("isVazio");
					else if (!(field.get(obj).toString()
							.matches("^[a-zA-ZÁ-Üá-ü]{1,}([ ]{1}[a-zA-ZÁ-Üá-ü\\.]{1,})*")))
						addMensagem("nonome");
				}

				if (anotacao instanceof Obrigatorio) {
					if (isVazio)
						addMensagem("isVazio");
					else {
						Obrigatorio obrig = (Obrigatorio) anotacao;
						if (!obrig.min().isEmpty())
							validaCampo(obrig.min(), field, obj, "nomin");

						if (!obrig.max().isEmpty())
							validaCampo(obrig.min(), field, obj, "nomax");
					}
				}
			}
		}
	}

	private void validaCampo(String valor, Field field, Object obj, String msg)
			throws Exception {

		String tipo = field.getType().getSimpleName().toUpperCase();
		if (tipo.equals("STRING")) {
			if (valor.compareTo(field.get(obj).toString()) > 0)
				addMensagem(msg);
		} else if (tipo.equals("INT")) {
			if (Integer.parseInt(valor) > field.getInt(obj))
				addMensagem(msg);
		} else if (tipo.equals("LONG")) {
			if (Long.parseLong(valor) > field.getLong(obj))
				addMensagem(msg);
		} else if (tipo.equals("DATE")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
			if (valor.equalsIgnoreCase("hoje"))
				valor = sdf.format(Utils.setData("hoje"));
			if (valor.compareTo(sdf.format(field.get(obj))) > 0)
				addMensagem(msg);
		}
	}

	public void limpaMensagens() {
		mensagens.clear();
	}

	private void addMensagem(String key) {
		mensagens.add(headerMensagem + prop.getProperty(key));
	}
}
